package cn.nebula.music.service;

import java.sql.Date;
import java.sql.Time;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.nebula.music.dao.AlbumSongDAO;
import cn.nebula.music.dao.CombinationSongDAO;
import cn.nebula.music.dao.LyricsDAO;
import cn.nebula.music.dao.SingerSongDAO;
import cn.nebula.music.dao.SongClassificationDAO;
import cn.nebula.music.dao.SongDAO;
import cn.nebula.music.dao.SongSonglistDAO;
import cn.nebula.music.domain.Album;
import cn.nebula.music.domain.AlbumSong;
import cn.nebula.music.domain.Classification;
import cn.nebula.music.domain.Combination;
import cn.nebula.music.domain.CombinationSong;
import cn.nebula.music.domain.Lyrics;
import cn.nebula.music.domain.Singer;
import cn.nebula.music.domain.SingerSong;
import cn.nebula.music.domain.Song;
import cn.nebula.music.domain.SongClassification;
import cn.nebula.music.domain.SongSonglist;
import cn.nebula.music.domain.Songlist;

@Service
public class SongServiceImpl implements SongService {

	@Autowired
	private SongDAO songDAO;

	@Autowired
	private LyricsDAO lyricsDAO;

	@Autowired
	private AlbumSongDAO albumSongDAO;

	@Autowired
	private SingerSongDAO singerSongDAO;

	@Autowired
	private CombinationSongDAO combinationSongDAO;

	@Autowired
	private SongClassificationDAO songClassificationDAO;

	@Autowired
	private SongSonglistDAO songSonglistDAO;

	@Override
	public Set<Song> findAllSongs() throws Exception {
		return songDAO.findAllSongs();
	}

	@Override
	public Set<Song> findAllSongsOfBT() throws Exception {
		return songDAO.findAllSongsOfBT();
	}

	@Override
	public Song findSongById(Integer id) throws Exception {
		return songDAO.findSongById(id);
	}

	@Override
	public Set<Song> findSongsByName(String name) throws Exception {
		return songDAO.findSongsByName(name);
	}

	@Override
	public Song findSongByResourcepath(String resourcepath) throws Exception {
		return songDAO.findSongByResourcepath(resourcepath);
	}

	@Override
	public Set<Song> findSongsByDuration(Time duration) throws Exception {
		return songDAO.findSongsByDuration(duration);
	}

	@Override
	public Set<Song> findSongsByLanguage(String language) throws Exception {
		return songDAO.findSongsByLanguage(language);
	}

	@Override
	public Set<Song> findSongsByPublishtime(Date publishtime) throws Exception {
		return songDAO.findSongsByPublishtime(publishtime);
	}

	@Override
	public Set<Song> findSongsByHeat(Integer heat) throws Exception {
		return songDAO.findSongsByHeat(heat);
	}

	@Override
	public Song findSongByMv(Integer mvId) throws Exception {
		return songDAO.findSongByMv(mvId);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void addSong(Song song) throws Exception {
		songDAO.addSong(song);
		Set<Lyrics> lyricses = song.getLyricses();
		if (lyricses != null) {
			for (Lyrics lyrics : lyricses) {
				Lyrics lyrics1 = lyricsDAO.findLyricsById(lyrics.getId());
				lyrics1.setSong(song);
				lyricsDAO.updateLyrics(lyrics1);
			}
		}
		Set<Album> albums = song.getAlbums();
		if (albums != null) {
			for (Album album : albums) {
				AlbumSong as = new AlbumSong();
				as.setAlbum(album.getId());
				as.setSong(song.getId());
				albumSongDAO.addAlbumSong(as);
			}
		}
		Set<Singer> singers = song.getSingers();
		if (singers != null) {
			for (Singer singer : singers) {
				SingerSong ss = new SingerSong();
				ss.setSinger(singer.getId());
				ss.setSong(song.getId());
				singerSongDAO.addSingerSong(ss);
			}
		}
		Set<Combination> combinations = song.getCombinations();
		if (combinations != null) {
			for (Combination combination : combinations) {
				CombinationSong cs = new CombinationSong();
				cs.setCombination(combination.getId());
				cs.setSong(song.getId());
				combinationSongDAO.addCombinationSong(cs);
			}
		}
		Set<Classification> classifications = song.getClassifications();
		if (classifications != null) {
			for (Classification classification : classifications) {
				SongClassification sc = new SongClassification();
				sc.setClassification(classification.getId());
				sc.setSong(song.getId());
				songClassificationDAO.addSongClassification(sc);
			}
		}
		Set<Songlist> songlists = song.getSonglists();
		if (songlists != null) {
			for (Songlist songlist : songlists) {
				SongSonglist ss = new SongSonglist();
				ss.setSonglist(songlist.getId());
				ss.setSong(song.getId());
				songSonglistDAO.addSongSonglist(ss);
			}
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void updateSong(Song song) throws Exception {
		songDAO.updateSong(song);
		Boolean isModify = false;
		int size1 = 0;// 更改前的数量
		int size2 = 0;// 更改后的数量
		Set<Lyrics> Lyricses1 = findSongById(song.getId()).getLyricses();
		Set<Lyrics> Lyricses2 = song.getLyricses();
		if (Lyricses1 != null) {
			size1 = Lyricses1.size();
		}
		if (Lyricses2 != null) {
			size2 = Lyricses2.size();
		}
		if (size1 == size2) {
			if (!Lyricses1.toString().equals(Lyricses2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Lyrics lyrics : Lyricses1) {
				Lyrics lyrics1 = lyricsDAO.findLyricsById(lyrics.getId());
				lyrics1.setSong(null);
				lyricsDAO.updateLyrics(lyrics1);
			}
			for (Lyrics lyrics : Lyricses2) {
				Lyrics lyrics1 = lyricsDAO.findLyricsById(lyrics.getId());
				lyrics1.setSong(song);
				lyricsDAO.updateLyrics(lyrics1);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Album> albums1 = findSongById(song.getId()).getAlbums();
		Set<Album> albums2 = song.getAlbums();
		if (albums1 != null) {
			size1 = albums1.size();
		}
		if (albums2 != null) {
			size2 = albums2.size();
		}
		if (size1 == size2) {
			if (!albums1.toString().equals(albums2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Album album : albums1) {
				AlbumSong as = new AlbumSong();
				as.setAlbum(album.getId());
				as.setSong(song.getId());
				albumSongDAO.deleteAlbumSong(as);
			}
			for (Album album : albums2) {
				AlbumSong as = new AlbumSong();
				as.setAlbum(album.getId());
				as.setSong(song.getId());
				albumSongDAO.addAlbumSong(as);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Singer> singers1 = findSongById(song.getId()).getSingers();
		Set<Singer> singers2 = song.getSingers();
		if (singers1 != null) {
			size1 = singers1.size();
		}
		if (singers2 != null) {
			size2 = singers2.size();
		}
		if (size1 == size2) {
			if (!singers1.toString().equals(singers2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Singer singer : singers1) {
				SingerSong ss = new SingerSong();
				ss.setSinger(singer.getId());
				ss.setSong(song.getId());
				singerSongDAO.deleteSingerSong(ss);
			}
			for (Singer singer : singers2) {
				SingerSong ss = new SingerSong();
				ss.setSinger(singer.getId());
				ss.setSong(song.getId());
				singerSongDAO.addSingerSong(ss);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Combination> combinations1 = findSongById(song.getId()).getCombinations();
		Set<Combination> combinations2 = song.getCombinations();
		if (combinations1 != null) {
			size1 = combinations1.size();
		}
		if (combinations2 != null) {
			size2 = combinations2.size();
		}
		if (size1 == size2) {
			if (!combinations1.toString().equals(combinations2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Combination combination : combinations1) {
				CombinationSong cs = new CombinationSong();
				cs.setCombination(combination.getId());
				cs.setSong(song.getId());
				combinationSongDAO.deleteCombinationSong(cs);
			}
			for (Combination combination : combinations2) {
				CombinationSong cs = new CombinationSong();
				cs.setCombination(combination.getId());
				cs.setSong(song.getId());
				combinationSongDAO.addCombinationSong(cs);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Classification> classifications1 = findSongById(song.getId()).getClassifications();
		Set<Classification> classifications2 = song.getClassifications();
		if (classifications1 != null) {
			size1 = classifications1.size();
		}
		if (classifications2 != null) {
			size2 = classifications2.size();
		}
		if (size1 == size2) {
			if (!classifications1.toString().equals(classifications2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Classification classification : classifications1) {
				SongClassification sc = new SongClassification();
				sc.setClassification(classification.getId());
				sc.setSong(song.getId());
				songClassificationDAO.deleteSongClassification(sc);
			}
			for (Classification classification : classifications2) {
				SongClassification sc = new SongClassification();
				sc.setClassification(classification.getId());
				sc.setSong(song.getId());
				songClassificationDAO.addSongClassification(sc);
			}
		}
		isModify = false;
		size1 = 0;// 更改前的数量
		size2 = 0;// 更改后的数量
		Set<Songlist> songlists1 = findSongById(song.getId()).getSonglists();
		Set<Songlist> songlists2 = song.getSonglists();
		if (songlists1 != null) {
			size1 = songlists1.size();
		}
		if (songlists2 != null) {
			size2 = songlists2.size();
		}
		if (size1 == size2) {
			if (!songlists1.toString().equals(songlists2.toString())) {
				isModify = true;
			}
		} else {
			isModify = true;
		}
		if (isModify == true) {
			for (Songlist songlist : songlists1) {
				SongSonglist ss = new SongSonglist();
				ss.setSonglist(songlist.getId());
				ss.setSong(song.getId());
				songSonglistDAO.deleteSongSonglist(ss);
			}
			for (Songlist songlist : songlists2) {
				SongSonglist ss = new SongSonglist();
				ss.setSonglist(songlist.getId());
				ss.setSong(song.getId());
				songSonglistDAO.addSongSonglist(ss);
			}
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void deleteSongById(Integer id) throws Exception {
		for (Lyrics lyrics : lyricsDAO.findAllLyricses()) {
			if (lyrics.getSong() != null && lyrics.getSong().getId().equals(id)) {
				lyrics.setSong(null);
				lyricsDAO.updateLyrics(lyrics);
			}
		}
		albumSongDAO.deleteAlbumSongBySongId(id);
		singerSongDAO.deleteSingerSongBySongId(id);
		combinationSongDAO.deleteCombinationSongBySongId(id);
		songClassificationDAO.deleteSongClassificationBySongId(id);
		songSonglistDAO.deleteSongSonglistBySongId(id);
		songDAO.deleteSongById(id);
	}

	@Override
	public List<Song> findNewSongs() throws Exception {
		return songDAO.findNewSongs();
	}

	@Override
	public List<Song> findHotSongs() throws Exception {
		return songDAO.findHotSongs();
	}

	@Override
	public List<Song> findHot4Songs() throws Exception {
		return songDAO.findHot4Songs();
	}

}
